package sing.myapp.ui.h5

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.webkit.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.alibaba.android.arouter.facade.annotation.Route
import com.github.lzyzsd.jsbridge.BridgeWebViewClient
import com.github.lzyzsd.jsbridge.CallBackFunction
import com.tbruyelle.rxpermissions3.RxPermissions
import sing.core.BuildConfig
import sing.core.base.BaseFragment
import sing.core.callback.Callback
import sing.core.dialog.CustomDialog
import sing.core.dialog.CustomDialog.OnClickListener
import sing.core.dialog.DownloadApk
import sing.core.dialog.ToOpenPermission
import sing.core.ext.util.loge
import sing.core.ext.util.showShort
import sing.core.ext.util.statusBarHeight
import sing.core.ext.view.clickNoRepeat
import sing.core.ext.view.isStatusBarBg
import sing.myapp.BR
import sing.myapp.R
import sing.myapp.databinding.FragmentH5Binding
import sing.myapp.router.RouterURL
import java.io.File


/**
 * @Description:    H5 的页面
 */
@Route(path = RouterURL.H5_FRAGMENT_WEB_VIEW)
class H5Fragment : BaseFragment<H5ViewModel, FragmentH5Binding>(R.layout.fragment_h5,BR.h5Vm) {

    var url = ""
    var title = "标题"
    var showTitle = false
    override fun initData() {
        super.initData()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            WebView.enableSlowWholeDocumentDraw()
        }

        val util = WebviewUtils(requireActivity(),db.webView)
        util.initWebViewSetting()
        util.goBack = goBack

        if (arguments == null){
            onBack()
            "参数错误".showShort()
        }else{
            url = requireArguments().getString("url","")
            if (url.isEmpty()){
                onBack()
                "参数错误".showShort()
                return
            }
            url = Uri.decode(url)
            title = requireArguments().getString("title","")
            if (title.equals("标题")){
                title = ""
            }

            val showBack = requireArguments().getBoolean("showBack",false)
            val isBlackBack = requireArguments().getBoolean("isBlackBack",true)
            db.ivBack.visibility = View.GONE
            db.ivBackWhite.visibility = View.GONE
            if (showBack){
                if (isBlackBack){
                    db.ivBack.visibility = View.VISIBLE
                }else{
                    db.ivBackWhite.visibility = View.VISIBLE
                }
            }

            showTitle = requireArguments().getBoolean("showTitle",false)
            if (showTitle){
                db.tvTitle.visibility = View.VISIBLE
                db.tvTitle.text = title
            }else{
                db.tvTitle.visibility = View.GONE
            }

            val showStatus = requireArguments().getBoolean("showStatus",false)
            if (showStatus){
                db.vStatus.visibility = View.VISIBLE
                db.vStatus.isStatusBarBg()
            }else{
                db.vStatus.visibility = View.GONE
            }

            db.llBackParent.setPadding(0,requireContext().statusBarHeight,0,0)
            db.ivBack.clickNoRepeat { onBack() }
            db.ivBackWhite.clickNoRepeat { onBack() }

            if (!url.startsWith("http") && !url.startsWith("file")){ // url不是网址的时候直接显示文字
                db.progressBar.visibility = View.GONE
                db.webView.visibility = View.GONE
                db.tvText.visibility = View.VISIBLE
                db.tvText.text = url
                return
            }else{
                db.progressBar.visibility = View.VISIBLE
                db.webView.visibility = View.VISIBLE
                db.tvText.visibility = View.GONE
            }

            db.webView.webChromeClient = webChromeClient
            db.webView.setDownloadListener(downloadListener)
            db.webView.webViewClient = object : BridgeWebViewClient(db.webView) {

                override fun shouldOverrideUrlLoading(view: WebView?, u: String?): Boolean {
                    try {
                        if (u == null) return false
                        if (u.startsWith("yy://")) {
                            return super.shouldOverrideUrlLoading(view, u);
                        }
                        if (u.startsWith("weixin://")) {
                            val intent =  Intent()
                            intent.action = Intent.ACTION_VIEW
                            intent.data = Uri.parse(url)
                            startActivity(intent)
                            return true
                        }
                        if(!u.startsWith("http://") && !u.startsWith("https://")) {
//                        val intent = Intent()
//                        intent.action = Intent.ACTION_VIEW
//                        val content_url = Uri.parse(u)
//                        intent.data = content_url
//                        startActivity(Intent.createChooser(intent, "请选择浏览器"))
                            return true
                        }
                        //处理http和https开头的url
//                    webView.loadUrl(u)
//                    return true
                        return super.shouldOverrideUrlLoading(view, u);
                    } catch (e: Exception) { //防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
                        return true//没有安装该app时，返回true，表示拦截自定义链接，但不跳转，避免弹出上面的错误页面
                    }
                }
            }
            "H5 --> $url".loge()

//            db.webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            // 禁用长按选择文字
            db.webView.setOnLongClickListener { true }
            db.webView.isLongClickable = false

            db.webView.loadUrl(url)
        }
    }

    // WebView监听
    private var webChromeClient = object : WebChromeClient() {
        override fun onProgressChanged(view: WebView, progress: Int) {
            if (progress == 100) {
                db.progressBar.visibility = View.GONE
                db.webView.scrollTo(0,0)
            } else {
                if (db.progressBar.visibility == View.GONE)
                    db.progressBar.visibility = View.VISIBLE
                db.progressBar.progress = progress;
            }
            super.onProgressChanged(view, progress)
        }

        override fun onReceivedTitle(view: WebView, title: String) {
            super.onReceivedTitle(view, title)
            if (!title.contains(".com") && !title.contains(".cn") && !title.contains("192.168") && !title.contains(".html") && showTitle) {
                db.tvTitle.text = title
            }else{
                db.tvTitle.text = this@H5Fragment.title
            }
        }

        // Android < 3.0 调用这个方法
        fun openFileChooser(filePathCallback: ValueCallback<Uri>) {
            uploadForAndroid5 = filePathCallback
            showPhoneDialog(arrayOf("*/*")) // 不适配
        }

        // 3.0 + 调用这个方法
        fun openFileChooser(filePathCallback: ValueCallback<Uri>, acceptType: String?) {
            uploadForAndroid5 = filePathCallback
            showPhoneDialog(arrayOf("*/*")) // 不适配
        }

        //  / js上传文件的<input type="file" name="fileField" id="fileField" />事件捕获
        // Android > 4.1.1 调用这个方法
        fun openFileChooser(filePathCallback: ValueCallback<Uri>, acceptType: String, capture: String?) {
            uploadForAndroid5 = filePathCallback
            showPhoneDialog(arrayOf(acceptType))
        }

        override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams): Boolean {
            uploadForAndroid5s = filePathCallback
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                showPhoneDialog(fileChooserParams.acceptTypes)
            } else {
                showPhoneDialog(arrayOf("*/*"))
            }
            return true
        }
    }

    // H5的打开媒体的选择
    private fun showPhoneDialog(acceptTypes: Array<String>) {
        this.acceptTypes = acceptTypes
        if (acceptTypes.isNotEmpty()){
            if (acceptTypes[0].contains("image")){
                selectImageDialog()
            }
        }else{
            chooseType = 2
            RxPermissions(this@H5Fragment)
                .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe { granted: Boolean ->
                    if (granted) {
                        doAction()
                    } else { // 没有权限
                        ToOpenPermission.requestDialog(requireActivity(), "存储", object : Callback {
                            override fun result(vararg data: Any) {
                                reSetH5()
                            }
                        })
                    }
                }
        }
    }
    var chooseType = 0 // 0是拍照 1是图库 2是其他

    // H5拍照、图库dialog
    private fun selectImageDialog(){
//        SelectImageDialog(requireActivity(), object : Callback {
//            override fun result(vararg data: Any) {
//                when {
//                    data[0] == 0 -> {// 拍照
//                        chooseType = 0
//                        RxPermissions(this@H5Fragment)
//                            .request(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
//                            .subscribe { granted: Boolean ->
//                                if (granted) {
//                                    doAction()
//                                } else { // 没有权限
//                                    requestDialog(requireActivity(), "相机、存储", object : Callback {
//                                        override fun result(vararg data: Any) {
//                                            reSetH5()
//                                        }
//                                    })
//                                }
//                            }
//                    }
//                    data[0] == 1 -> {// 从相册选择
//                        chooseType = 1
//                        RxPermissions(this@H5Fragment)
//                            .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
//                            .subscribe { granted: Boolean ->
//                                if (granted) {
//                                    doAction()
//                                } else { // 没有权限
//                                    requestDialog(requireActivity(), "存储", object : Callback {
//                                        override fun result(vararg data: Any) {
//                                            reSetH5()
//                                        }
//                                    })
//                                }
//                            }
//                    }
//                    else -> {
//                        reSetH5()
//                    }
//                }
//            }
//        }).show()
    }

    private fun reSetH5(){
        if(uploadForAndroid5s !=null){
            uploadForAndroid5s!!.onReceiveValue(null)
            uploadForAndroid5s = null
        }
        if (uploadForAndroid5 !=null){
            uploadForAndroid5!!.onReceiveValue(null)
            uploadForAndroid5 = null
        }
    }

    private fun doAction(){
        val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
        var intent: Intent? = null
        when (chooseType) {
            0 -> {
                contentSelectionIntent.type = "image/*"
                intent = createCameraIntent()
            }
            1 -> {
                contentSelectionIntent.type = "image/*"
                intent = Intent(Intent.ACTION_CHOOSER)
            }
            2 -> {
                if ("" == acceptTypes[0]) {
                    contentSelectionIntent.type = "*/*"
                } else {
                    contentSelectionIntent.type = acceptTypes[0]
                }
                intent = Intent(Intent.ACTION_CHOOSER)
            }
        }

        intent?.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
        intent?.putExtra(Intent.EXTRA_TITLE, "选择文件")
        startActivityForResult(intent, 1001)
    }

    var acceptTypes: Array<String> = arrayOf("")
    private var uploadForAndroid5s: ValueCallback<Array<Uri>>? = null
    private var uploadForAndroid5: ValueCallback<Uri>? = null
    private var mCameraFilePath: String? = null

    // 拍照的Intent
    private fun createCameraIntent(): Intent {
        val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val externalDataDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
        val cameraDataDir = File(externalDataDir.absolutePath + File.separator)
        cameraDataDir.mkdirs()
        var mCameraFilePath = (cameraDataDir.absolutePath + File.separator + System.currentTimeMillis() + ".jpg")
        this.mCameraFilePath = mCameraFilePath
        cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0)
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(requireContext(), BuildConfig.AUTHORITIES, File(mCameraFilePath)))
        return cameraIntent
    }
    // 下载监听
    private var downloadListener = DownloadListener { url, _, _, _, _ ->
        val dialog = CustomDialog(requireContext())
        dialog.setMsg("即将下载该文件，是否继续？")
        dialog.addListener(object : OnClickListener{
            override fun confirm(dialog: androidx.appcompat.app.AlertDialog?) {
                super.confirm(dialog)
                try {
                    if (url.endsWith(".apk")){
                        RxPermissions(this@H5Fragment)
                            .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            .subscribe { granted: Boolean ->
                                if (granted) {
                                    val d = DownloadApk(activity!!,url)
                                    d.start()
                                } else { // 没有权限
                                    ToOpenPermission.requestDialog(requireActivity(), "存储",null)
                                }
                            }
                    }else{
                        val intent = Intent()
                        intent.action = Intent.ACTION_VIEW
                        intent.data = Uri.parse(url)
                        startActivity(Intent.createChooser(intent, "请选择浏览器"))
                    }
                } catch (e: Exception) {
                    "无法下载该文件".showShort()
                }
            }
        })
        dialog.show()
    }

    override fun lazyLoadData() {
    }

    override fun createObserver() {
    }

    private fun onBack() {
        if (db.webView.canGoBack()) {
            db.webView.goBack()
        } else {
            requireActivity().onBackPressed()
        }
    }

    private var function: CallBackFunction? = null

    private var appGetImgPathFunction: CallBackFunction? = null


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                1001 ->{ // H5流，H5打开拍照、图库、文件等
                    if (null != uploadForAndroid5) {
                        if (mCameraFilePath != null) {
                            val uri = Uri.fromFile(File(mCameraFilePath))
                            uploadForAndroid5!!.onReceiveValue(uri) // 返回H5的文件流，
                        } else {
                            val result = if (data == null || resultCode != AppCompatActivity.RESULT_OK) null else data.data
                            if (result != null) {
                                uploadForAndroid5!!.onReceiveValue(result)
                            } else {
                                uploadForAndroid5!!.onReceiveValue(null)
                            }
                        }
                        uploadForAndroid5 = null
                    }
                    if (null != uploadForAndroid5s) {
                        if (mCameraFilePath != null) {
                            val uri = Uri.fromFile(File(mCameraFilePath))
                            uploadForAndroid5s!!.onReceiveValue(arrayOf(uri))
                        } else {
                            val result = if (data == null || resultCode != AppCompatActivity.RESULT_OK) null else data.data
                            if (result != null) {
                                uploadForAndroid5s!!.onReceiveValue(arrayOf(result))
                            } else {
                                uploadForAndroid5s!!.onReceiveValue(null)
                            }
                        }
                        uploadForAndroid5s = null
                    }
                }
            }
        }else{
            reSetH5()
        }
        mCameraFilePath = null
    }

    var isFirst = true
    override fun onResume() {
        super.onResume()
        if (!isFirst){
            db.webView.callHandler("initMyData","",null)
        }
        isFirst = false
    }
    // 后退
    private val goBack = object : WebviewUtils.GoBack{
        override fun goBack(type:Int) {
            if (type == 0){
                onBack()
            }else{
                activity?.finish()
            }
        }
    }
}